#ifndef LINUX_GLOBAL_H
#define LINUX_GLOBAL_H

#include <types.h>

#define GDT_SIZE    0x100

#define SEG_ATTR_G          (1 << 15)
#define SEG_ATTR_D          (1 << 14)
#define SEG_ATTR_P          (1 << 7)

#define SEG_ATTR_DPL0       (0 << 5)
#define SEG_ATTR_DPL3       (3 << 5)

#define SEG_ATTR_CPL0       (0 << 0)
#define SEG_ATTR_CPL3       (3 << 0)

#define SEG_SYSTEM          (0 << 4)
#define SEG_NORMAL          (1 << 4)
#define SEG_TYPE_DATA       (0 << 3)
#define SEG_TYPE_CODE       (1 << 3)
#define SEG_TYPE_RW         (1 << 1)
#define SEG_TYPE_TSS        (9 << 0)

typedef struct gdt_table_t
{
    uint16_t limit_l;
    uint16_t base_l;
    uint8_t base_m;
    uint16_t attr;
    uint8_t base_h;
} _packed gdt_table_t;

extern gdt_table_t gdt_table[GDT_SIZE];

void init_gdt();

void init_gdt32(gdt_table_t *gdt_table);

uint32_t get_gdt_table_entry();

void free_gdt_table_entry(uint32_t selector);

gdt_table_t *get_gdt_table();

void set_gdt_table_entry(int selector, uint32_t base, uint32_t limit, uint16_t attr);

#define GATE_TYPE_IDT		(0xE << 8)		// 中断32位门描述符
#define GATE_TYPE_SYSCALL   (0xC << 8)		// 系统调用32位门描述符
#define GATE_ATTR_P 		(1 << 15)		// 是否存在
#define GATE_ATTR_DPL0		(0 << 13)		// 特权级0，最高特权级
#define GATE_ATTR_DPL3		(3 << 13)		// 特权级3，最低权限

typedef struct gdt_gate_t
{
    uint16_t offset_l;
    uint16_t selector;
    uint16_t attr;
    uint8_t offset_h;
} _packed gdt_gate_t;

void set_gdt_gate_entry(gdt_gate_t * desc, uint16_t selector, uint32_t offset, uint16_t attr);

#endif